package com.hengfoxwolf.ffmpegdemo
import android.os.Bundle
import android.util.Log
import com.hengfoxwolf.ffmpegdemo.base.BaseActivity
import com.hengfoxwolf.ffmpegdemo.databinding.ActivityFlowCaseBinding
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

class FlowCaseActivity : BaseActivity<ActivityFlowCaseBinding>(ActivityFlowCaseBinding::inflate) {

    override fun init(savedInstanceState: Bundle?) {

//        launch {
//            flow {
//                for (i in 0.until(3)) {
//                    emit(i)
//                    delay(1000)
//                }
//            }.collect {
//                Log.d(TAG,"value:${it}")
//            }
//        }

//        launch {
//            flow {
//                for (i in 0.until(3)) {
//                    emit(i)
//                    delay(1000)
//                }
//            }.onEach {
//                Log.d(TAG,"onEach:${it}")
//            }.onCompletion{
//                Log.d(TAG,"onCompletion")
//            }.launchIn(this)
//        }


        //zip操作符---合并,延时后不会影响合并结果
        launch {
            val numbers = flowOf(1, 2, 3).onEach {
                delay(200)
            }
            val strings = flowOf("one", "two", "three").onEach {
                delay(400)
            }
            val startTime = System.currentTimeMillis()
            numbers.zip(strings) {
                    a,b->"${a}-->${b}"
            }.collect {
               Log.d(TAG,"zipValue:${it};:diffTime:${System.currentTimeMillis() - startTime}")
            }
        }

        //combine操作符---合并,延时后每次都会重写计算,影响合并结果
        launch {
            val numbers = flowOf(1, 2, 3).onEach {
                delay(200)
            }
            val strings = flowOf("one", "two", "three").onEach {
                delay(400)
            }
            val startTime = System.currentTimeMillis()
            numbers.combine(strings) {
                a,b -> "${a}--${b}"
            }.collect {
                Log.d(TAG, "combineValue:${it};diffTime:${System.currentTimeMillis() - startTime}")
            }
        }

        //flatMapConcat操作符---串行(按顺序)打印
        flatMapConcat()

        //flatMapMerge操作符---并行(先执行完一个,在执行完另外一个)打印
        flatMapMerge()

        //conflate操作符---获取最新值,中间可能跳过某些值
        conflate()
    }

    private fun requestFlow(i: Int) : Flow<String> = flow {
        emit("$i First")
        delay(500)
        emit("$i Second")
    }

    @OptIn(FlowPreview::class)
    private fun flatMapConcat() {
        val startTime = System.currentTimeMillis()
        launch {
            (1..3).asFlow().onEach {
                delay(800)
            }.flatMapConcat {
                requestFlow(it)
            }.collect {
                Log.d(TAG, "flatMapConcat:${it};diffTime:${System.currentTimeMillis() - startTime}")
            }
        }
    }

    @OptIn(FlowPreview::class)
    private fun flatMapMerge() {
        val startTime = System.currentTimeMillis()
        launch {
            (1..3).asFlow().onEach {
                delay(100)
            }.flatMapMerge {
                requestFlow(it)
            }.collect {
                Log.d(TAG, "flatMapMerge:${it};diffTime:${System.currentTimeMillis() - startTime}")
            }
        }
    }

    private fun conflate() {
        launch {
            flow {
                for (i in 1..3) {
                    delay(100)
                    emit(i)
                    Log.d(TAG,"conflate--emit-${i}")
                }
            }.conflate().collect {
                delay(500)
                Log.d(TAG,"conflate--collect-${it}")
            }
        }
    }

    companion object {
        const val TAG = "FlowCaseActivity"
    }
}